#!/usr/bin/php
<?php
require_once('include/common.php');
require_once('include/shard-key-mapper.php');
require_once('include/mysql.php');
define('DEBUG',false);

function main() {
	$params = get_commandline();
	if(has_short_opt(array('h','help'), $params)) {
		shard_query_common_help();
		directory_setup_help();
		exit;
	}

	$defaults = get_defaults($params);
	$shards = get_shards($params);


	if(empty($shards['directory'])) {
		die("You must have a [directory] entry in the .ini file.\n");
	}

	if(!empty($defaults['mapper'])) {
		$defaults['mapper'] = 'directory';
	} 

	$directory = $shards['directory'];
	unset($shards['directory']);

	$mapper = new DirectoryShardKeyMapper($directory);
	$conn = new MySQLDAL();
	$conn->my_connect($directory);

	if($conn->my_error()) die('Could not connect to directory!\n' . $conn->my_error() . "\n");

	if(empty($defaults['schema_name'])) {
		$schema_name = 'default';
	} else {
		$schema_name = $defaults['schema_name'];
		unset($defaults['schema_name']);
	}

	if(empty($defaults['gearman'])) {
		$gearman = array( array('hostname' => '127.0.0.1', 'port' => 7000 ) );
	} else {
		$gearman = $defaults['gearman'];
		unset($defaults['gearman']);

		$gearmen = explode(',', $gearman);
		$gearman = array();
		foreach($gearmen as $server) {
			list($host, $port) = explode(':', $server);
			$gearman[] = array( 'host' => $host, 'port' => $port ); 
			
		}
	}

	if(empty($defaults['column'])) {
		die('You must specify a column as the sharding key.\n');
	} else {
		$column = $defaults['column'];
		unset($defaults['column']);
	}

	if(empty($defaults['datatype'])) {
		die('You must specify a column datatype for the sharding key (string or integer).\n');
	} else {
		$datatype = $defaults['datatype'];
		unset($defaults['datatype']);
	}
	
	#DESTRUCTIVE - comment out if you want to drop the store	
	#echo "Dropping schema\n";
	#$mapper->drop_store();

	#echo "Creating new schema data store\n";
	#$mapper->create_store();

	echo "Virtual schema name: " . $schema_name . "\n";
	echo "Registering new virtual schemea\n";
	$conn->my_query('BEGIN');
	$stmt = $conn->my_query("select id from schemata where schema_name='" . $conn->my_escape_string($schema_name) . "'");
	if(!$stmt) die($conn->my_error() . "\n");

	$row = $conn->my_fetch_assoc($stmt);
	if($row) {
		die('Schema already exists with id: ' . $row['id'] . "\n");
	}
	
	$sql = "insert into schemata (schema_name) values('" . $conn->my_escape_string($schema_name) . "')";
	$conn->my_query($sql) or die($conn->my_error());

	$schema_id = $conn->my_insert_id();

	if(!empty($defaults['coord_shard'])) {
		$coord_shard_name = $defaults['coord_shard'];
		unset($defaults['coord_shard']);
	} else {
		$coord_shard_name = null;
	}

	echo "Populating configuration values\n";
	foreach($defaults as $var_name => $var_value) {
		$sql = "insert into schemata_config(schema_id, var_name, var_value) values($schema_id, '" . $conn->my_escape_string($var_name) . "','" . $conn->my_escape_string($var_value) . "')";
		$conn->my_query($sql) or die($conn->my_error());
	}	

	echo "Populating shard list\n";
	foreach($shards as $shard_name => $shard) {
		if(empty($shard['user'])) $username = "NULL"; else $username="'" . $shard['user'] . "'";
		if(empty($shard['db'])) $db = "NULL"; else $db="'" . $shard['db'] . "'";
		if(empty($shard['password'])) $password = "NULL"; else $password="'" . $shard['password'] . "'";
		if(empty($shard['port'])) $port = "NULL"; else $port=$shard['port'];
		if(empty($shard['host'])) $host = "NULL"; else $host="'" . $shard['host'] . "'";
		if(empty($shard['shard_rdbms'])) $shard_rdbms = "'mysql'"; else $shard_rdbms="'" . $shard['shard_rdbms'] . "'";
		if(!isset($coord_shard_name) || (isset($coord_shard_name) && $shard_name == $coord_shard_name)) $coord_shard = 1; else $coord_shard = 0; 
		$accepts_new_rows = 1;
		$extra_info = "NULL";

		$sql = "INSERT INTO shards (schema_id, shard_name, extra_info, shard_rdbms, coord_shard, accepts_new_rows, username, password, host, port, db) VALUES(";
		$sql .= "$schema_id, '$shard_name',$extra_info,$shard_rdbms,$coord_shard,$accepts_new_rows,$username,$password,$host,$port,$db)"; 

		$conn->my_query($sql) or die($conn->my_error() . "\n");
	}			

	
	echo "Populating gearman servers\n";
	foreach($gearman as $server) {
		$sql = "INSERT INTO gearman_job_servers (schema_id, hostname, port) VALUES(";
		$sql .= "$schema_id, '{$server['host']}',{$server['port']})"; 

		$conn->my_query($sql) or die($conn->my_error() . "\n");
	
	}

	echo "Populating gearman functions\n";
	$sql = "INSERT INTO gearman_functions(schema_id,function_name_id, worker_count, is_enabled)
                select $schema_id,id, 5, 1
		from gearman_function_names;";
	$conn->my_query($sql) or die($conn->my_error() . "\n");

	$conn->my_query('ROLLBACK');
	echo "Done!\n";

}

function get_shards($params, $return_defaults=false) {
	$shards = array();

	if(!empty($params['ini'])) {
		$filename = $params['ini'];
	} else { 
		$filename = 'shards.ini';
	}
	if(!file_exists($filename)) {
		die("Could not find settings file: $filename (use genconfig)\n");
	}
	$shards = @parse_ini_file($filename, true);

	if(!empty($shards['default'])) {
		if($return_defaults) {
			return $shards['default'];
		}
		$defaults = $shards['default'];

		unset($shards['default']);
	} else {
		$defaults = array('host' => '127.0.0.1', 'port'=>3306, 'user'=> 'root', 'db' => 'test','password' => '');
	}


	foreach($defaults as $key => $val) {
		if(!empty($params[$key])) $defaults[$key] = $params[$key];
	}

	
	$shard_keys = array_keys($shards);
	
	#populate missing values with the defaults, in case any INI sections are missing things like 'db'
	for($i=0;$i<count($shard_keys);++$i) {
		foreach($defaults as $key => $val) {
			if (empty($shards[$shard_keys[$i]][$key]) || $shards[$shard_keys[$i]][$key] == '') {
				$shards[$shard_keys[$i]][$key] = $val;
			}
		}

		if(empty($shards[$shard_keys[$i]]['db'])) $shards[$shard_keys[$i]]['db'] = $shard_keys[$i];
	}

	return $shards;
}

main();
exit;
